package com.hnchances.security;

import cn.hutool.json.JSONUtil;
import com.hnchances.util.RedisClient;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Objects;

/**
 * 自定义过滤器，实现token令牌的判断
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private final static String TOKEN_NAME = "Authorization";

    private final RedisClient redisClient;

    public JwtAuthenticationTokenFilter(RedisClient redisClient) {
        this.redisClient = redisClient;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取请求头
        String token = request.getHeader(TOKEN_NAME);
        if(StringUtils.hasLength(token)){
            // 从redis中获取用户信息
            String key = "login:token:"+token;
            String json = redisClient.get(key);
            if(StringUtils.hasLength(json)){
                // 反序列化，将json字符串转换为对象
                LoginUserDetails user = JSONUtil.toBean(json, LoginUserDetails.class);
                // 判断user不为空
                if(Objects.nonNull(user)){
                   //封装用户信息,送到下一个过滤器  UsernamePasswordAuthenticationFilter
                    UsernamePasswordAuthenticationToken authenticationFilter = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities());
                    //将Redis数据库中的信息送到SpringSecurity上下文中
                    SecurityContextHolder.getContext().setAuthentication(authenticationFilter);
                }else {
                    SecurityContextHolder.getContext().setAuthentication(null);
                }
            }
        }
        //放行,后面交给Spring Security 框架
        filterChain.doFilter(request,response);
    }
}
